home *** CD-ROM | disk | FTP | other *** search
/ The Word 6 / The Word 6.adf / FiLeS / AMOS4.txt / AMOS4.txt
Text File  |  2022-11-05  |  14KB  |  319 lines

  1. |AMOS Programming Tutorial
  2.  
  3.  
  4.  
  5. by Freak of NFA
  6.  
  7. Hopefully  you're  following this little tutorial/hint guide okay and my
  8. explanations  and methods don't leave you thinking "what the bloody hell
  9. is HE smoking man?", certainly nobody has written to me saying that they
  10. can't follow them, I assume then that things are progressing smoothly...
  11.  
  12. |Part 4 - Text Files
  13.  
  14.  
  15.  
  16. One of the things I've been asked about a lot recently is how to include
  17. ASCII  text  files  in AMOS programs, mainly by people wanting to create
  18. their  own  disk-lists or disk-based magazines but getting stuck at this
  19. point.  It may sound laughable - "just load it in!" I hear you cry - but
  20. getting it to work, and more importantly getting it to work FAST, can be
  21. bloody infuriating without some help.
  22.  
  23. I've  been  using  the  same method for a while now, I've leaked the odd
  24. secret or two to a couple of people but now with this new-found sense of
  25. open-ness  and  honesty,  I feel it's time to let you have the full low-
  26. down on how to get text files into your programs.
  27.  
  28. |Loading...
  29.  
  30.  
  31.  
  32. Before  we can start doing things with the text file we've obviously got
  33. to get it loaded into AMOS, into a bank where we can get our hands on it
  34. more easily.  Sifting through data in RAM is immensly quicker than doing
  35. the  same  with a disk so it makes sense to load the whole file in first
  36. rather than load one line at a time from disk, right?  The obvious draw-
  37. back  with  this  is  that  the  memory usage will be higher, but you'll
  38. simply  have  to  make sure you have sufficient room left for it, and in
  39. all honesty, usage isn't too bad.
  40.  
  41. To load the file in:
  42.  
  43.     '------------------------------------ Load file into bank 10
  44.     FILE$="Docs/MyTextFile.txt"
  45.     Open in 1,FILE$
  46.         Reserve as Work 10,Lof(1)
  47.         Bload FILE$,Start(10)
  48.     Close 1
  49.  
  50. The  filename is stored in FILE$, you open channel one to it, reserve as
  51. much  RAM  as you need for this RAW bank, load it in as Binary data, and
  52. close the channel.  Another good thing about this method is that you can
  53. crunch  your  text  file  using  Powerpacker or Crunchmania and with the
  54. relevent  patch  you  can  load  the file in as normal, making for great
  55. savings  in  filespace.   The  Word  uses Crunchmania and the RTDD patch
  56. until we can get the Assembler source sorted out.
  57.  
  58. You'll  decide exactly what FILE$ will hold through some sort of menu or
  59. from  a  keypress,  anything that lets the user make a decision.  In The
  60. Word  it's  taken  from the y-position of the selector bar, added to the
  61. lines that the screen is actually offset (if you've scrolled it down for
  62. example), how you decide which file to load is up to you.
  63.  
  64. Because  this  file has been loaded as binary data it has not been split
  65. into  seperate  lines,  and so if you look into RAM you'll find that the
  66. strings (individual text lines) are all in one big continuous block, and
  67. seperated  by character 10 - the EOL character.  Just because these 10's
  68. are there doesn't mean to say your text is already formatted!
  69.  
  70. Your startup-sequence may look like this in CygnusEd:
  71.                                                             (fig.1)
  72.     .-------------------------------------------------------------.
  73.     |   Makedir RAM:ENV RAM:ENV/Sys RAM:T                         |
  74.     |                                                             |
  75.     |   Assign ENV: RAM:ENV                                       |
  76.     |   Assign A: SYS:A                                           |
  77.     |   Assign T: Ram:T                                           |
  78.     |   Assign Utils: SYS:Utilities/                              |
  79.     |                                                             |
  80.     |   CopyMemQuicker >Nil:                                      |
  81.     |   NoKlik >Nil:                                              |
  82.     |   CacheFont >Nil:                                           |
  83.     |                                                             |
  84.     |   Run >Nil: C:FreakBoot                                     |
  85.     |   Endcli >Nil:                                              |
  86.     |                                                             |
  87.     |<------------------- Width of text Page -------------------->|
  88.     `-------------------------------------------------------------'
  89.  
  90. But  as far as your memory is concerned it will look like this:  (I have
  91. used "#" in place of the character 10's...)
  92.                                                             (fig.2)
  93.     .-------------------------------------------------------------.
  94.     |Makedir RAM:ENV RAM:ENV/Sys RAM:T##Assign ENV: RAM:ENV#Assign|
  95.     |A: SYS:A#Assign T: Ram:T#Assign Utils: SYS:Utilities/##CopyMe|
  96.     |mQuicker >Nil:#NoKlik >Nil:#CacheFont >Nil:##Run >Nil: C:Frea|
  97.     |kBoot#Endcli >Nil:                                           |
  98.     |                                                             |
  99.     |                                                             |
  100.     |<---------------- Width of your Memory Block --------------->|
  101.     `-------------------------------------------------------------'
  102.  
  103. Remember,  although I have conveniently slotted the above into a "block"
  104. of  memory  x-bytes wide it is actually a continuous lump, and the width
  105. divisions do not physically exist.  You can see the above string by
  106. going to direct mode and typing:
  107.  
  108.                Print Peek$(Start(10),Length(10)) <Return>
  109.  
  110. What  we  have  to  do is "format" the RAW bank file into something that
  111. represents  the  CygnusEd  screen in fig.1 and we need to do it fast, as
  112. our  document  may contain a lot of lines, and we don't want to keep our
  113. user waiting while we crawl through a massive file!
  114.  
  115. |Counting Lines...
  116.  
  117.  
  118.  
  119. You  see  this line appear in PPMore and Opus, "Counting Lines" it says,
  120. BOLLOCKS!   I  say,  what it's really doing is formatting your text into
  121. something useable!
  122.  
  123. You  DO  actually  have  to  count the number of lines in your text file
  124. before  you  can  start  to  play with it, and this can be handled quite
  125. easily with the following little routine:
  126.  
  127.     '----------------------------------------------- Count Lines
  128.     POS=Start(10) : LINES=0
  129.  
  130.     Do 
  131.         Exit If POS>=Start(10)+Length(10)
  132.         H=Hunt(POS To Start(10)+Length(10),Chr$(10))
  133.         Exit If H=0 or H=Start(10)+Length(10)
  134.         Inc LINES
  135.         POS=H+1
  136.     Loop 
  137.  
  138. In  this  bit,  you  start at the beginning of bank 10 and keep track of
  139. where you are in the bank with the POS variable.  The Hunt() function is
  140. a  bloody  quick  way  of looking for a specific value, and to count the
  141. number  of lines in our doc all we have to really do is count the number
  142. of  times  Chr$(10) appears, character 10 is the End Of Line (EOL) char,
  143. remember?   If  you've found one, and you haven't reached the end of the
  144. bank  (Start(10)+Length(10))  then  you set POS to one PAST the EOL char
  145. that you've just found and continue your search.
  146.  
  147. When  all  is  done, the LINES variable will hold the number of lines in
  148. your document, now you can start chopping bank 10 up into something more
  149. managable, individual lines.
  150.  
  151.     '------------------------------------- Text into TXT$()
  152.     POS=Start(10)
  153.     Dim TXT$(LINES)
  154.  
  155.     For LINE=1 To LINES
  156.         H=Hunt(POS To Start(10)+Length(10),Chr$(10))
  157.         TL=1+(H-POS) : TXT$=Space$(TL)
  158.         Copy POS,POS+TL To Varptr(TXT$)
  159.         TXT$(LINE)=TXT$-Chr$(10)
  160.         POS=H+1
  161.     Next LINE
  162.  
  163. The  more  astute  of  you will realise that these last two routines are
  164. incredibly  similar,  that  both  use the Hunt() function in exactly the
  165. same  way  so  can they be combined into one loop instead of two?  Well,
  166. they  can  if  you  have  the same memory area reserved for each of your
  167. files, but that would mean having to reserve memory for the biggest file
  168. that you've got ALL the time.
  169.  
  170. The  speed  that you require is gained from using the Amiga Blitter chip
  171. to  format  your text with the Copy command.  In the above you reserve a
  172. place  to  put your new line (T$=Space$(), above) and copy the data into
  173. it at the highest speed possible.
  174.  
  175. You'll  see above that I have put the lines of text into an array called
  176. (not  suprisingly) TXT$().  This method would be used for something that
  177. would  only need defining once, like the menu on a disk-mag, because you
  178. don't  want  to  have  to  call Dim TXT$() for each document, it is very
  179. wasteful and slow as far as RAM is concerned.
  180.  
  181. The  other way to do it is to format the RAW bank into another bank, and
  182. then  take  the data from this bank as you need it.  You would replace a
  183. few  of  the  lines of the above routine but the essential functionality
  184. remains the same.  The altered routine goes like this:
  185.  
  186.     '------------------------------------- Text into Bank 11
  187.     POS=Start(10) : PAGEWIDTH=60
  188.     Reserve as Work 11,LINES*PAGEWIDTH
  189.     '----------------------------------- Fill bank with Spaces
  190.     A$="    " : Fill Start(11),Start(11)+Length(11),Leek(Varptr(A$))
  191.  
  192.     For LINE=1 To LINES
  193.         H=Hunt(POS To Start(10)+Length(10),Chr$(10))
  194.         TL=(H-POS) : If TL>PAGEWIDTH Then TL=PAGEWIDTH
  195.         Copy POS,POS+TL To Start(11)+((LINE-1)*PAGEWIDTH)
  196.         POS=H+1
  197.     Next LINE
  198.  
  199. This  one  is  not only much, much faster than the above, but there's no
  200. slow-down  where AMOS performs a garbage-collection run due to excessive
  201. use  of  strings  by your program, so this is ideal for articles and the
  202. like,  the bank can be erased when you've finished with it, and you have
  203. complete control over every byte.
  204.  
  205. |Outputting Text...
  206.  
  207.  
  208.  
  209. Now  that  you've  got  your  text  file in RAM in a format that you can
  210. easily  get  at,  it's  time  to give the user something to look at, and
  211. because  you  have your text all nicely formatted and available, this is
  212. the easiest thing in the world!
  213.  
  214. ==========
  215. Example 1:
  216. ==========
  217. You  want  to display a certain page of the menu in your disk-mag, there
  218. are  LPP Lines on each page (LPP = Lines Per Page) and you want the text
  219. lines  10  pixels  apart  so that you can do a nice copper bar effect to
  220. follow your mouse pointer for a selection method:
  221.  
  222. Easy!   You've  formatted  each line into an array called TXT$() because
  223. you want to be able to use the strings in this array as headers as well,
  224. so getting any particular line is as easy as looking in the array!
  225.  
  226.         T$=TXT$(LINE)
  227.         Print T$
  228.  
  229. Was that so difficult?  No.
  230.  
  231. To display the menu page you need to define a start line and an end line
  232. depending on LPP (Lines Per Page) and the actual page number:
  233.  
  234.     '------------------------------------------ Setup Values
  235.     LPP=15 : PAGE=1 : XPOS=20
  236.     PAGES=LINES/LPP : If PAGES*LPP<>LINES Then Inc PAGES
  237.  
  238.     '----------------------------------------- Start and End lines
  239.     ST=(PAGE-1)*LPP
  240.     ND=ST+LPP-1 : IF ND>LINES Then ND=LINES
  241.  
  242.     '---------------------------------------- Display the Page
  243.     For LINE=ST To ND
  244.         YPOS=20+((LINE-1)*10)
  245.         T$=TXT$(LINE)
  246.         Text XPOS,YPOS,T$
  247.     Next LINE
  248.  
  249. All  you  really  have  to watch out for is the PAGE variable, make sure
  250. that there is no way it can go above the actual number of pages that you
  251. have  got,  which is stored in PAGES, and that it doesn't go below 1, if
  252. it does either of these things you'll get an error.
  253.  
  254. ==========
  255. Example 2:
  256. ==========
  257. Your  user  has  selected  an article and you've loaded it, formatted it
  258. into bank 11, and now you want to display the first page.  There are now
  259. TLPP  lines  on  each  article page (TLPP = Text Lines Per Page) and you
  260. want  the  lines  every 8 pixels so that all your funky ASCII logos look
  261. dead groovy with no silly lines...
  262.  
  263.     '--------------------------------------------- Setup Values
  264.     TLPP=20 : SHEET=1 : PAGEWIDTH=60
  265.     SHEETS=TLINES/TLPP : If SHEETS*TLPP<>TLINES Then Inc SHEETS
  266.  
  267.     '----------------------------------------- Start and End lines
  268.     ST=(SHEET-1)*TLPP
  269.     ND=ST+LPP-1 : IF ND>TLINES Then ND=TLINES
  270.  
  271.     '---------------------------------------- Display the Page
  272.     For TLINE=ST To ND
  273.         YPOS=20+((TLINE-1)*8)
  274.         T$=Space$(PAGEWIDTH)
  275.         SRC=Start(11)+((SHEET-1)*(TLPP*PAGEWIDTH))+((TLINE-1)*PAGEWIDTH)
  276.         Copy SRC,SRC+(PAGEWIDTH-1) To Varptr(T$)
  277.         Text XPOS,YPOS,T$
  278.     Next TLINE
  279.  
  280. This one is a little more complicated that before, because again you are
  281. using  the  blitter  to  grab your lines of text straight out of the RAM
  282. bank  and  put them straight into T$, as quickly as possible.  I've also
  283. used  new  variables, SHEET, SHEETS, TLINES, and TLPP in place of others
  284. so  that  you don't end up using the same variables for different things
  285. and so get yourselves into a mess:
  286.  
  287. SHEET   -   Instead of PAGE, it contains the current SHEET number
  288.  
  289. SHEETS  -   Instead of PAGES, contains the maximum number of SHEETS
  290.  
  291. TLINES  -   Replaces LINES, just the number of lines in the article
  292.  
  293. TLPP    -   Aready explained, the number of lines of text on each page
  294.  
  295. The  same  wornings apply as in Example1, in that you should not let the
  296. SHEET  variable  go above SHEETS or below 1, otherwise you risk crashing
  297. your Amiga completely!
  298.  
  299. The  Word uses a mixture of these two for the Menu, and uses a variation
  300. of  Example 2 for it's articles, so you can see that these routines work
  301. absolutely  fine.  That said I haven't TESTED any of the above code, the
  302. formatting routines were from "Balls!" so they should work fine, but the
  303. output  routines I just made up off the top of my head, so if they don't
  304. work, FIX THE BUGGERS!
  305.  
  306. If  you have any suggestions to make with regards to improving my source
  307. code  or  you've found bugs due to my lack of testing, write in to me at
  308. the  usual  address and I'll publish an amendment in the next issue.  If
  309. you've  written  something  incredible and you want to share it with the
  310. rest of the Amiga/AMOS world, this is the place to send it!
  311.  
  312. Have fun people!!!
  313.  
  314.  
  315. |Freak of NFA
  316.  
  317.  
  318.                  Support the Amiga - Kill the Consoles!
  319.